package com.desire.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.desire.bean.TokenVerifyBean;
import com.desire.config.autoconfig.TokenProperties;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * @author LittleDesire
 * @description
 * @date 2022-05-09 周一 16:11
 * @since 17
 */
public class TokenUtils {
    @Autowired
    TokenProperties tokenProperties;
    /**
     * 默认加密算法
     */
    private final String ALGORITHM = "HMAC256";
    private final String ISSUER = "littledesire";


    /**
     * 生成 token
     *
     * @param map
     * @return
     */
    public String generateToken(Map map) {
        return JWT.create()
                .withHeader(getHeader())
                .withPayload(parsePayload(map))
                .withIssuer(ISSUER)
                .withExpiresAt(getExpiresDate())
                .sign(Algorithm.HMAC256(tokenProperties.getSecret()));
    }

    /**
     * 计算token有效时间
     * @return
     */
    Date getExpiresDate() {
        long time = (long) this.tokenProperties.getValidateTime() * 1000 * 60;
        return new Date(System.currentTimeMillis()+time);
    }


    /**
     * 对token进行验证
     *
     * @param token token
     * @return payload 信息，code==1 通过验证
     */
    public TokenVerifyBean verifyToken(String token) {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(tokenProperties.getSecret()))
                .withIssuer(ISSUER)
                .build();
        DecodedJWT decodedJWT = null;
        try {
            decodedJWT = verifier.verify(token);
        }catch (TokenExpiredException te){
            return new TokenVerifyBean(1, "token已过期！", null);
        } catch (JWTDecodeException e) {
            return new TokenVerifyBean(0, "token无效", null);
        }
        return new TokenVerifyBean(200, "token验证通过", decodedJWT.getClaims());
    }

    /**
     * 对map做一个判断，当有key和value时才放入到map当中
     *
     * @param map
     * @return
     */
    Map parsePayload(Map map) {
        Map rsMap = new HashMap();
        Set<Map.Entry<String, Object>> set = map.entrySet();
        Iterator<Map.Entry<String, Object>> iterator = set.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            if (null != entry.getKey() && null != entry.getValue()) {
                rsMap.put(entry.getKey(), entry.getValue());
            }
        }
        return rsMap;
    }

    private Map getHeader() {
        Map<String, Object> map = new HashMap<>();
        map.put("typ", "jwt");
        map.put("alg", ALGORITHM);
        return map;
    }
}
